package core.process.pack;

import core.aln.pair.Paln;
import core.utils.EPara;
import core.rb.PB;
import core.rb.MB;
import core.rb.r.PR;
import core.rb.r.Pol;
import core.rb.r.MR;
import core.sb.SB;
import core.sb.s.Seq;
import gui.processor.Processor;
import gui.utils.ProgBar;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

/*Author: John Archer, Contact: john.archer.jpa@gmail.com*/
public class AlignPack extends Thread{
    private PB pOut;
    private final CountDownLatch stopLatch;
    private MB pIn;
    private Processor gp;
    public AlignPack(Processor gp, CountDownLatch stopLatch, MB p){
        this.stopLatch = stopLatch;
        this.gp = gp;
        this.pIn = p;
        this.start();
    }
    public void run(){
        pOut = align();
        stopLatch.countDown();
    }
    public void setPIn(MB pack){pIn = pack;}
    public PB getPOut(){return pOut;}
    public PB align(){
        PB pb = new PB(new Seq(pIn.getRef().getTitle(),pIn.getRef().getDNA()));
        Paln pa = new Paln(EPara.GO,EPara.GE,EPara.MAT,EPara.MIS);
        if(gp!=null){
            gp.dPrg(ProgBar.START, pIn.getSize());
            for (int x = 0; x < pIn.getSize(); x++) {
                pb.add(align(pIn.getRead(x), pIn.getRef().getDNA(), pa));
                gp.dPrg(ProgBar.UPDATE, x);
            }
            gp.dPrg(ProgBar.END, 0);
        }
        else{for (int x = 0; x < pIn.getSize(); x++){pb.add(align(pIn.getRead(x), pIn.getRef().getDNA(), pa));}}
        return pb;
    }

    private PR align(MR wmr, String ref, Paln lpa){
        return setPols(wmr.getStart(), wmr.getI(), wmr.getRev(), lpa.getAln(ref.substring(wmr.getStart(), wmr.getEnd()), new String(wmr.getDNA()), new String(wmr.getQuals())));
    }

    private PR setPols(int start, int i, boolean rev, SB aln) {
        start += Paln.START_OF_REF_NOT_USED;

        int c = 0;
        while (aln.get(0).getDNA().charAt(c) == '-'){c++;}
        aln.get(0).setDNA(aln.get(0).getDNA().substring(c));
        aln.get(1).setDNA(aln.get(1).getDNA().substring(c));
        aln.get(2).setDNA(aln.get(2).getDNA().substring(c));

        c = 0;
        while (aln.get(1).getDNA().charAt(c) == '-') {c++;}
        int tStart = start + c;
        String tBit = aln.get(0).getDNA().substring(c);
        String rBit = aln.get(1).getDNA().substring(c);
        String quls = aln.get(2).getDNA().substring(c);

        c = 0;
        for (int x = 0; x < tBit.length(); x++){if(tBit.charAt(x) == '-'){c++;}}
        int endTLoc = tStart + (tBit.length() - c);

        ArrayList <Pol> pols = new ArrayList();
        int tIns = 1;
        int tInNoGap = 0;
        for (int t = 0; t < tBit.length(); t++) {
            if(tBit.charAt(t) == rBit.charAt(t)){tIns = 1; tInNoGap++;}
            else if(tBit.charAt(t) == '-'){
                pols.add(new Pol(rBit.charAt(t),quls.charAt(t),tStart+tInNoGap,tIns++,tBit.charAt(t)));
            }
            else{
                tIns = 1;
                pols.add(new Pol(rBit.charAt(t),quls.charAt(t),tStart+tInNoGap,0,tBit.charAt(t)));
                tInNoGap++;
            }
        }
        return new PR(i, tStart, endTLoc, pols, rev);
    }
}